package com.kova.api.crypto;

//import com.sun.org.apache.xerces.internal.impl.dv.util.Base64;
//import sun.misc.BASE64Decoder;
//import sun.misc.BASE64Encoder;

import org.apache.commons.codec.binary.Base64;
import org.springframework.util.StringUtils;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import java.security.SecureRandom;


public class AesCrypto implements KeyCrypto {

    /** 密钥长度: 128, 192 or 256 */
    private static final int KEY_SIZE = 128;

    /** 加密/解密算法名称 */
    private static final String ALGORITHM = "AES";

    /** 随机数生成器（RNG）算法名称 */
    private static final String RNG_ALGORITHM = "SHA1PRNG";

    private String seed;
    public AesCrypto(String seed){
        this.seed = seed;
    }
    public AesCrypto(){}

    @Override
    public KeyCrypto setKey(String key) {
        this.seed = key;
        return this;
    }

    @Override
    public byte[] encrypt(byte[] plainBytes) {

        try {

            //byte[] plainBytes=content.getBytes();
            byte[] key=this.seed.getBytes();
            // 生成密钥对象
            SecretKey secKey = generateKey(key);

            // 获取 AES 密码器
            Cipher cipher = Cipher.getInstance(ALGORITHM);
            // 初始化密码器（加密模型）
            cipher.init(Cipher.ENCRYPT_MODE, secKey);

            // 加密数据, 返回密文
            byte[] cipherBytes = cipher.doFinal(plainBytes);

            return cipherBytes;
            // 通过Base64转码返回(不然会报错)
            //return Base64.encodeBase64String(cipherBytes);
            //return new String(cipherBytes);

        }catch (Exception ex){
            throw new CryptoException(ex);
        }

        /**
        try {
            //1.构造密钥生成器，指定为AES算法,不区分大小写
            KeyGenerator keygen = KeyGenerator.getInstance("AES");
            //2.根据ecnodeRules规则初始化密钥生成器
            SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG" );
            secureRandom.setSeed(this.seed.getBytes(CharsetUtil.UTF_8));
            //生成一个128位的随机源,根据传入的字节数组,不能超过128，否则抛出异常，是因为美国对软件出口的限制
            keygen.init(128,secureRandom);
            //3.产生原始对称密钥
            SecretKey original_key = keygen.generateKey();
            //4.获得原始对称密钥的字节数组
            byte[] raw = original_key.getEncoded();
            //5.根据字节数组生成AES密钥
            SecretKey key = new SecretKeySpec(raw, "AES");
            //6.根据指定算法AES自成密码器
            Cipher cipher = Cipher.getInstance("AES");
            //7.初始化密码器，第一个参数为加密(Encrypt_mode)或者解密解密(Decrypt_mode)操作，第二个参数为使用的KEY
            cipher.init(Cipher.ENCRYPT_MODE, key);
            //9.根据密码器的初始化方式--加密：将数据加密
            return cipher.doFinal(src);
        } catch (Exception e) {
            throw new CryptoException(e);
        }
         **/
    }

    @Override
    public byte[] decrypt(byte[] src) {



        try {

            byte[] key = this.seed.getBytes();
            // 生成密钥对象
            SecretKey secKey = generateKey(key);

            // 获取 AES 密码器
            Cipher cipher = Cipher.getInstance(ALGORITHM);
            // 初始化密码器（解密模型）
            cipher.init(Cipher.DECRYPT_MODE, secKey);

            // 解密数据, 返回明文
            byte[] plainBytes = cipher.doFinal(Base64.decodeBase64(src));

            return plainBytes;
            //return new String(plainBytes, "utf-8");
            //return new String(plainBytes);

        }catch (Exception ex){
            throw new CryptoException(ex);
        }

        /**
        try {
            //1.构造密钥生成器，指定为AES算法,不区分大小写
            KeyGenerator keygen = KeyGenerator.getInstance("AES");
            SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG" );
            secureRandom.setSeed(this.seed.getBytes(CharsetUtil.UTF_8));
            //2.根据ecnodeRules规则初始化密钥生成器
            //生成一个128位的随机源,根据传入的字节数组
            keygen.init(128, secureRandom);
            //3.产生原始对称密钥
            SecretKey original_key = keygen.generateKey();
            //4.获得原始对称密钥的字节数组
            byte[] raw = original_key.getEncoded();
            //5.根据字节数组生成AES密钥
            SecretKey key = new SecretKeySpec(raw, "AES");
            //6.根据指定算法AES自成密码器
            Cipher cipher = Cipher.getInstance("AES");
            //7.初始化密码器，第一个参数为加密(Encrypt_mode)或者解密(Decrypt_mode)操作，第二个参数为使用的KEY
            cipher.init(Cipher.DECRYPT_MODE, key);

            return  cipher.doFinal(src);
        } catch (Exception e) {
            throw new CryptoException(e);
        }
         **/
    }

    @Override
    public String encrypt(String content, String charset) {
        if (StringUtils.isEmpty(content) || StringUtils.isEmpty(seed)){
            return "";
        }

        try {

            byte[] plainBytes=content.getBytes();
            byte[] key=seed.getBytes();
            // 生成密钥对象
            SecretKey secKey = generateKey(key);

            // 获取 AES 密码器
            Cipher cipher = Cipher.getInstance(ALGORITHM);
            // 初始化密码器（加密模型）
            cipher.init(Cipher.ENCRYPT_MODE, secKey);

            // 加密数据, 返回密文
            byte[] cipherBytes = cipher.doFinal(plainBytes);

            // 通过Base64转码返回(不然会报错)
            return Base64.encodeBase64String(cipherBytes);
            //return new String(cipherBytes);

        }catch (Exception ex){
            ex.printStackTrace();
            return "";
        }
        /**
        try {
            byte[] encrypt = encrypt(src.getBytes(charset));

            return Base64.encodeBase64String(encrypt);
            //return new BASE64Encoder().encode(encrypt);
        } catch (Exception e) {
            throw new CryptoException(e);
        }
         **/
    }

    @Override
    public String decrypt(String content, String charset) {

        if (StringUtils.isEmpty(content) || StringUtils.isEmpty(seed)){
            return "";
        }

        try {

            byte[] key = seed.getBytes();
            // 生成密钥对象
            SecretKey secKey = generateKey(key);

            // 获取 AES 密码器
            Cipher cipher = Cipher.getInstance(ALGORITHM);
            // 初始化密码器（解密模型）
            cipher.init(Cipher.DECRYPT_MODE, secKey);

            // 解密数据, 返回明文
            byte[] plainBytes = cipher.doFinal(Base64.decodeBase64(content));

            return new String(plainBytes, "utf-8");
            //return new String(plainBytes);

        }catch (Exception ex){
            ex.printStackTrace();
            return "";
        }
        /**
        try {
            //byte[] bytes = new BASE64Decoder().decodeBuffer(src);
            byte[] bytes = Base64.decodeBase64(src);

            byte[] decrypt = decrypt(bytes);
            return new String(decrypt , charset);
        } catch (Exception e) {
            throw new CryptoException(e);
        }
         **/
    }

    /**
     * 生成密钥对象
     */
    private SecretKey generateKey(byte[] key) throws Exception {
        // 创建安全随机数生成器
        SecureRandom random = SecureRandom.getInstance(RNG_ALGORITHM);
        // 设置 密钥key的字节数组 作为安全随机数生成器的种子
        random.setSeed(key);

        // 创建 AES算法生成器
        KeyGenerator gen = KeyGenerator.getInstance(ALGORITHM);
        // 初始化算法生成器
        gen.init(KEY_SIZE, random);

        // 生成 AES密钥对象, 也可以直接创建密钥对象: return new SecretKeySpec(key, ALGORITHM);
        return gen.generateKey();
    }
}
